
.text
.global _start
_start:
@Address Exception Mode in Entry
@0x00000000 Reset                 Supervisor
reset_entry:
    b reset

@0x00000004 Undefined instruction Undefined
undef_instruction_entry:
    b undef_instruction_entry

@0x00000008 Software Interrupt    Supervisor
swi_entry:
    b swi_entry

@0x0000000C Abort (prefetch)      Abort
abort_prefetch_entry:
    b abort_prefetch_entry

@0x00000010 Abort (data)          Abort
abort_data_entry:
    b abort_data_entry

@0x00000014 Reserved              Reserved
reserved_entry:
    b reserved_entry

@0x00000018 IRQ                   IRQ
    b irq_entry @NOTE:when irq occured, svc's next pc instruction was filled to lr automaticly.

@0x0000001C FIQ                   FIQ
frq_entry:
    b frq_entry

reset:
    ldr sp, =1024 * 4
    bl close_watch_dog
    bl init_clock
    bl init_sdram
    bl copy_main_code_nand2sdram

	/*
	7  6  5  4  3  2  1  0
	I  F  T  1  0  0  1  0
	|  |  |  -------------
	|  |  |        |_Interupt Mode
	|  |  |_0:not Thumb mode
	|  |_1:disable Fast Interupt
	|_1:disable Interupt
	*/
    msr cpsr_c, #0xd2 @set to irq mode. cpsr_c is cpsr[0:7] bits
    ldr sp, =0x33000000 @0x30000000+16*1024*1024=0x32000000 -> 16M position as irq's stack. [0x33000000, 0x32000000) size:16M

    msr cpsr_c, #0xd3 @set to svc supervisor mode
    ldr sp, =1024 * 4


    bl init_irq
    msr cpsr_c, #0x53; @open Interupt by setting cpsr_c.I bit

    ldr sp, =0x34000000       @0x30000000+64*1024*1024 64M position   [0x3400000, 0x33000000) size:16M
    ldr lr, =halt_loop        @set return_address
    ldr pc, =pre_main             @jump to pre_main,run on sdram.

halt_loop:
    b halt_loop

irq_entry:
    sub lr, lr, #4 @calc lr, this lr is irq's lr,but the value is filled with svc mode's next instruction when irq occured.
    stmdb sp!, {r0-r12, lr}

	ldr r0, =0x4A000014 @INTOFFSET addr
	ldr r0, [r0]
	cmp r0, #11 @is INT_TIMER1?
	beq os_timer_irq
	b comm_irq

os_timer_irq:
	@step1:save {r0-r12, lr} to current task struct register buffer. to cur_task_info.regs
	mov r0, sp
	ldr r1, =g_pcurrent_regs @load g_pcurrent_regs the pointer's value, check please! todo.
	ldr r1, [r1]

	ldr r3, [r0] @orig's r0
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r1
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r2
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r3
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r4
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r5
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r6
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r7
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r8
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r9
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r10
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r11
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	ldr r3, [r0] @orig's r12
	str r3, [r1]
	add r1, r1, #4
	add r0, r0, #4

	@ldr r3, [r0] @orig's r13(sp). can not see in int-mode
	@str r3, [r1]
	add r1, r1, #4
	@add r0, r0, #4

	@ldr r3, [r0] @orig's r14(lr). can not see in int-mode
	@str r3, [r1]
	add r1, r1, #4
	@add r0, r0, #4

	ldr r3, [r0] @orig's r15, filled with int-mode's lr
	str r3, [r1]
	add r1, r1, #4
	@add r0, r0, #4

	mrs r3, spsr
	str r3, [r1] @orig's cpsr, filled with int-mode's spsr


	@step2:set =save_sp_and_lr to lr
	ldr r1, =save_sp_and_lr
	str r1, [r0] @now r0 is point to lr's addr

	@step3:close interupt
	ldr r0, =0x4a000000 @rSRCPND
	@ldr r1, =0x800 @1 << 11
	ldr r1, [r0]
	str r1, [r0]

	ldr r0, =0x4a000010 @rINTPND
	@ldr r1, =0x800 @1 << 11
	ldr r1, [r0]
	str r1, [r0]


	@for debug start
	@close INT_TIME1 for OS timer
	ldr r0, =0x4a000008 @INTMSK
	ldr r1, =0xEFFFFFE8 @ 0xEFFFF7E8 -> 0xEFFFFFE8
@	str r1, [r0]
	@for debug end

	@step4:run on save_sp_and_lr
	ldmia sp!, {r0-r12, pc}^ @recover int-mode's sp, and run on schedule

.global save_sp_and_lr
save_sp_and_lr:
	ldr r0,=g_pcurrent_regs
	ldr r0, [r0]
	add r0, r0, #52 @13*4, now r0 -> sp position
	str sp, [r0]
	add r0, r0, #4 @now r0 -> lr position
	str lr, [r0]
	ldr pc, =schedule @run on schedule

comm_irq:
    ldr lr, =irq_int_return
    ldr pc, =int_service

irq_int_return:
    ldmia sp!, {r0-r12, pc}^ @^ means irq's spsr copy to user_mode's cpsr























